package com.hua.service.impl;
import java.math.BigDecimal;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hua.common.ResponseCode;
import com.hua.domain.OrderCommodity;
import com.hua.domain.Orders;
import com.hua.domain.domainVo.UserOrder;
import com.hua.exception.BusinessException;
import com.hua.mapper.OrdersMapper;
import com.hua.service.OrdersService;
import com.hua.util.RedisCache;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

import static com.hua.constant.RedisConstant.REDIS_ORDERS_KEY;

/**
 * @author chenlong
 * @description 针对表【orders(订单表 用以存储我们的订单)】的数据库操作Service实现
 * @createDate 2022-10-21 22:43:16
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders>
        implements OrdersService {

    /**
     * 订单的mapper
     */
    @Resource
    private OrdersMapper ordersMapper;

    @Resource
    private RedisCache redisCache;

    /**
     * 查询用户所有的订单
     *
     * @param useId 用户的id
     * @return 查询到的用户的订单集合
     */
    @Override
    public List<UserOrder> userOrderList(Long useId) {
        final String key = REDIS_ORDERS_KEY + useId;
        //从缓存中查询数据 如果有直接返回
        List<UserOrder> cacheList = redisCache.getCacheList(key);
        if(cacheList != null && cacheList.size() > 0){
            return cacheList;
        }
        //防止storeId  是空
        if (useId == null) {
            throw new BusinessException(ResponseCode.PARAMS_NULL_ERROR, "用户信息异常");
        }
        //查询用户所购买的商品
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        //找到相同用户id 的订单
        queryWrapper.eq(Orders::getUserId, useId);
        //查询到的订单集合
        List<Orders> orders = ordersMapper.selectList(queryWrapper);
        //用户需要的订单
        List<UserOrder> userOrders = new ArrayList<>();
        orders.parallelStream()
                .forEach(o -> {
                    //我们的返回信息
                    UserOrder userOrder = new UserOrder();
                    userOrder.setOrders(o);
                    //查询每笔订单的商品详情  通过订单去商品白哦里面找到相应的商品信息
                    userOrder.setOrderCommodityList(ordersMapper.orderContent(o.getOrderId()));
                    userOrders.add(userOrder);
                });
        redisCache.setCacheList(key, orders);
        return userOrders;
    }

    /**
     * 保存订单的信息   （没有相关的商品信息）
     *
     * @param order 订单的实体类
     * @return 订单的id
     */
    @Override
    @Transactional
    public Long saveOrder(Orders order) {
        //防止订单信息有误
        if (order == null || order.getUserId() == null || order.getUserId() <= 0) {
            throw new BusinessException(ResponseCode.PARAMS_NULL_ERROR, "订单创建失败");
        }
        //生成订单的id
        String orderNumber = UUID.randomUUID().toString();
        order.setOrderNumber(orderNumber);
        //手动设置订单的id
        //插入数据
        List<Orders> dayOrders = ordersMapper.selectDayCount();
        order.setIsCompleted(0);
        order.setQueueNum(dayOrders.size());
        //我们的redis的key
        ReentrantLock lock = new ReentrantLock();
        try {
            lock.lock();
            AtomicInteger frontSum = new AtomicInteger();
            //找出当天的数据
            dayOrders
                    .parallelStream()
                    .forEach(orders -> {
                        Integer isCompleted = orders.getIsCompleted();
                        if(isCompleted != null && isCompleted == 0) frontSum.getAndIncrement();
                    });
            order.setFrontNum(frontSum.get());
            //插入订单
            int insert = ordersMapper.insert(order);
            if (insert <= 0) {
                throw new BusinessException(ResponseCode.UPDATE_ERROR, "生成订单失败");
            }
            //查询出我们刚插入的订单
            LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Orders::getOrderNumber, orderNumber);
            Orders orders = ordersMapper.selectOne(queryWrapper);
            //防止订单获取失败
            if (orders == null || orders.getOrderId() <= 0) {
                throw new BusinessException(ResponseCode.UPDATE_ERROR, "生成订单失败");
            }
            String key = REDIS_ORDERS_KEY + order.getUserId();
            //删除缓存
            redisCache.deleteObject(key);
            //返回订单id
            return orders.getOrderId();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 下单 添加订单的商品信息
     *
     * @param orderId            订单did
     * @param orderCommodityList 订单的商品的集合
     */
    @Override
    @Transactional
    public UserOrder saveOrderAddCommodity(
            Long orderId,
            List<OrderCommodity> orderCommodityList) {
        //防止订单中商品出错
        if(orderCommodityList == null || orderCommodityList.isEmpty()) {
            throw new BusinessException(ResponseCode.UPDATE_ERROR, "订单保存失败");
        }
        //查看我们的订单信息
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Orders::getOrderId, orderId);
        Orders orders = ordersMapper.selectOne(queryWrapper);
        //防止订单异常
        if (orders == null || orders.getUserId() == null) {
            throw new BusinessException(ResponseCode.UPDATE_ERROR, "下单失败");
        }
        ReentrantLock lock = new ReentrantLock();
        try {
            BigDecimal totalPrice = new BigDecimal("0.0");
            lock.lock();
            //把数据存到数据数据库
            for (OrderCommodity orderCommodity : orderCommodityList) {
                String commodityInfo = orderCommodity.getCommodityInfo();
                String commodityDesc = orderCommodity.getCommodityDesc();
                BigDecimal commodityPrice = orderCommodity.getCommodityPrice();
                Integer commodityCount = orderCommodity.getCommodityCount();
                Long userId = orderCommodity.getUserId();
                Long comOrderId = orderCommodity.getOrderId();
                String commodityImg = orderCommodity.getCommodityImg();
                Integer commodityId = orderCommodity.getCommodityId();

                boolean res = ordersMapper.insertOrderCommodity(
                        commodityInfo,
                        commodityDesc,
                        commodityPrice,
                        commodityCount,
                        userId,
                        comOrderId,
                        commodityImg,
                        commodityId
                );
                if(!res){
                    throw new BusinessException(ResponseCode.UPDATE_ERROR, "添加订单失败");
                }
                totalPrice = totalPrice.add(commodityPrice);
            }
            //查询我们生成的商品信息
            List<OrderCommodity> orderCommodities = ordersMapper.orderContent(orderId);
            if(orderCommodities == null || orderCommodities.isEmpty()) {
                throw new BusinessException(ResponseCode.UPDATE_ERROR, "添加订单信息失败");
            }
            orders.setPayedPrice(totalPrice);
                    //redis的key
            String key = REDIS_ORDERS_KEY + orders.getUserId();
            //删除缓存
            redisCache.deleteObject(key);
            //返回订单
            UserOrder userOrder = new UserOrder();
            userOrder.setOrders(orders);
            userOrder.setOrderCommodityList(orderCommodities);
            return userOrder;
        }finally {
            lock.unlock();
        }

    }

    /**
     * 删除订单
     *
     * @param orderId 订单id
     * @return 删除的结果
     */
    @Override
    @Transactional
    public Boolean deleteOrder(String orderId) {
        //防止订单中商品出错
        if(orderId == null || orderId.equals("") ){
            throw new BusinessException(ResponseCode.PARAMS_NULL_ERROR, "删除订单失败");
        }
        //防止订单中商品出错
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        //关联订单id
        queryWrapper.eq(Orders::getOrderId, orderId);
        //进行真正的删除
        Orders orders = ordersMapper.selectOne(queryWrapper);
        int delete = ordersMapper.logicalDelete(orderId);
        Long userId = orders.getUserId();
        if(userId == null || userId <= 0) {
            throw new BusinessException(ResponseCode.PARAMS_ERROR,"删除失败");
        }
        String key = REDIS_ORDERS_KEY + userId;
        if (redisCache.getCacheList(key) != null) {
            redisCache.deleteObject(key);
        }
        return Boolean.TRUE.equals(delete == 1);
    }

    /**
     * 删除多个订单
     *
     * @param orderIds 订单的id
     * @return 是否删除成功
     */
    @Override
    @Transactional
    public Boolean deleteOrders(List<Long> orderIds) {
        //防止订单中商品出错
        if(orderIds == null || orderIds.isEmpty()){
            throw new BusinessException(ResponseCode.PARAMS_NULL_ERROR, "删除订单失败");
        }
        for (Long orderId : orderIds) {
            Boolean aBoolean = this.deleteOrder(String.valueOf(orderId));
            if (aBoolean.equals(false)) {
                throw new BusinessException(ResponseCode.UPDATE_ERROR, "删除失败");
            }
        }
        return Boolean.TRUE;
    }

}




